package main

import "fmt"

// 递归 ， 自行理解

// 闭包：
// 	1、闭包是指有权访问另一个函数作用域中的变量的函数。
// 	2、创建团包的常见的方式就是在一个函数内部创建另一个函数，通过另一个函数访问这个函数的局部变量
// 注意:由于闭包里作用域返回的局部变量资源不会被立刻销毁回收，所以可能会占用更多的内存。过度使用闭包会导致性能下降，建议在非常有必要的时候才使用闭包。

// 闭包的写法： 函数返回值为函数

func adder() func() int {
	var i = 10
	return func() int {
		return i + 1
	}
}

func adder2() func(y int) int {
	// .\main.go:22:33: undefined: y
	// fmt.Printf("adder-header: %v", y)
	var i = 10
	fmt.Printf("adder-middle: %v\n", i)
	return func(y int) int {
		i += y
		fmt.Printf("adder-closePackage: %v\n", i)
		return i
	}
}
func main() {
	// var fn = adder()
	// fmt.Println(fn()) // 11
	// fmt.Println(fn()) // 11
	// fmt.Println(fn()) // 11

	// 闭包函数被初始化后， 内部内容不在重新初始化
	var fn2 = adder2()
	fmt.Printf("%T", fn2)
	fmt.Println(fn2(10)) // 20
	// fmt.Println(fn2(10)) // 30
	// fmt.Println(fn2(10)) // 40

}
